#include "localwordmanager.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QStandardPaths>
#include <QDir>
#include <QDebug>

namespace WordMemory
{

LocalWordManager &LocalWordManager::instance()
{
    static LocalWordManager inst;
    return inst;
}

LocalWordManager::LocalWordManager(QObject *parent)
    : QObject(parent), m_isLoaded(false)
{
    loadWordsFromFile();
}

QString LocalWordManager::getStorageFilePath() const
{
    if (!UserManager::instance().isLoggedIn()) {
        qWarning() << "LocalWordManager: No user logged in, cannot determine storage path.";
        return QString();
    }
    int userId = UserManager::instance().getUserId();
    QString dataPath = QDir::currentPath()
            + "/app_data"
            + "/user_" + QString::number(userId);

    QDir dir(dataPath);
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            qWarning() << "LocalWordManager: Could not create user data directory:" << dataPath;
        }
    }
    return dataPath + "/downloaded_words.json";
}

bool LocalWordManager::loadWordsFromFile()
{
    m_downloadedWords.clear();
    QString filePath = getStorageFilePath();
    if (filePath.isEmpty()) {
        m_isLoaded = false;
        return false;
    }

    QFile file(filePath);
    if (!file.exists()) {
        m_isLoaded = true;
        return true;
    }

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "LocalWordManager: Couldn't open downloaded words file for reading:" << file.errorString();
        m_isLoaded = false;
        return false;
    }

    QByteArray data = file.readAll();
    file.close();

    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull() || !doc.isArray()) {
        qWarning() << "LocalWordManager: Invalid JSON format in downloaded words file.";

        m_isLoaded = false;
        return false;
    }

    QJsonArray wordArray = doc.array();
    for (const QJsonValue &value : wordArray) {
        if (value.isObject()) {
            m_downloadedWords.append(Word::fromJson(value.toObject()));
        }
    }
    m_isLoaded = true;
    qDebug() << "LocalWordManager: Loaded" << m_downloadedWords.count() << "words from" << filePath;
    return true;
}

bool LocalWordManager::saveWordsToFile() const
{
    if (!m_isLoaded) {
        qWarning() << "LocalWordManager: Words not loaded, cannot save.";
        return false;
    }
    QString filePath = getStorageFilePath();
    if (filePath.isEmpty()) {
        return false;
    }

    QJsonArray wordArray;
    for (const Word &word : m_downloadedWords) {
        wordArray.append(word.toJson());
    }
    QJsonDocument doc(wordArray);

    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
        qWarning() << "LocalWordManager: Couldn't open downloaded words file for writing:" << file.errorString();
        return false;
    }

    file.write(doc.toJson());
    file.close();
    qDebug() << "LocalWordManager: Saved" << m_downloadedWords.count() << "words to" << filePath;
    return true;
}

bool LocalWordManager::saveWord(const Word &word)
{
    if (!m_isLoaded) {
        loadWordsFromFile(); // Attempt to load if not already
        if (!m_isLoaded) return false;
    }

    if (word.id == 0) {
        qWarning() << "LocalWordManager: Attempted to save word with ID 0.";
        return false;
    }

    for (const Word &existingWord : m_downloadedWords) {
        if (existingWord.id == word.id) {
            qDebug() << "LocalWordManager: Word" << word.word << "already downloaded.";
            return true;
        }
    }

    m_downloadedWords.append(word);
    bool success = saveWordsToFile();
    if (success) {
        emit downloadedWordsChanged();
    }
    return success;
}

QList<Word> LocalWordManager::loadDownloadedWords()
{
    if (!m_isLoaded) {
        loadWordsFromFile();
    }
    return m_downloadedWords;
}

bool LocalWordManager::isWordDownloaded(int wordId) const
{
    if (!m_isLoaded && const_cast<LocalWordManager*>(this)->loadWordsFromFile()) {
      // Successfully loaded, proceed
    } else if (!m_isLoaded) {
        return false;
    }

    for (const Word &word : m_downloadedWords) {
        if (word.id == wordId) {
            return true;
        }
    }
    return false;
}

bool LocalWordManager::removeWord(int wordId)
{
    if (!m_isLoaded) {
        loadWordsFromFile();
        if (!m_isLoaded) return false;
    }

    bool found = false;
    for (int i = 0; i < m_downloadedWords.size(); ++i) {
        if (m_downloadedWords[i].id == wordId) {
            m_downloadedWords.removeAt(i);
            found = true;
            break;
        }
    }

    if (found) {
        bool success = saveWordsToFile();
        if (success) {
            emit downloadedWordsChanged();
        }
        return success;
    }
    return false;
}

} // namespace WordMemory
